1 using System;
2 using
UnityEngine;
3
4 namespace
ProceduralToolkit
5 {

6     ///
<summary>
7     ///
Collection of drawing method-independent generic drawing algorithms
8     ///
</summary>
9     
public static class Draw
10     {
11         
public delegate void DebugDrawLine(Vector3 start, Vector3 end, Color color, float duration, bool depthTest);
12
13         
private const int circleSegments = 64;
14         
private const float circleSegmentAngle = 360f/circleSegments;
15
16         
private static readonly Func<float, float, Vector3> pointOnCircleXY;
17         
private static readonly Func<float, float, Vector3> pointOnCircleXZ;
18         
private static readonly Func<float, float, Vector3> pointOnCircleYZ;
19
20         
static Draw()
21         {
22             pointOnCircleXY = PTUtils.PointOnCircle3XY;
23             pointOnCircleXZ = PTUtils.PointOnCircle3XZ;
24             pointOnCircleYZ = PTUtils.PointOnCircle3YZ;
25         }
26
27         
#region Raster
28
29         ///
<summary>
30         ///
Draws aliased line and calls <paramref name="draw"/> on every pixel
31         ///
</summary>
32         ///
<remarks>
33         ///
https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
34         ///
</remarks>
35         
public static void RasterLine(Vector2Int v0, Vector2Int v1, Action<int, int> draw)
36         {
37             RasterLine(v0.x, v0.y, v1.x, v1.y, draw);
38         }

39
40         ///
<summary>
41         ///
Draws aliased line and calls <paramref name="draw"/> on every pixel
42         ///
</summary>
43         ///
<remarks>
44         ///
https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
45         ///
</remarks>
46         
public static void RasterLine(int x0, int y0, int x1, int y1, Action<int, int> draw)
47         {
48             
bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
49             
if (steep)
50             {
51                 PTUtils.Swap(
ref x0, ref y0);
52                 PTUtils.Swap(
ref x1, ref y1);
53             }
54             
if (x0 > x1)
55             {
56                 PTUtils.Swap(
ref x0, ref x1);
57                 PTUtils.Swap(
ref y0, ref y1);
58             }
59
60             
int dx = x1 - x0;
61             
int dy = Math.Abs(y1 - y0);
62             
int error = dx/2;
63             
int ystep = (y0 < y1) ? 1 : -1;
64             
int y = y0;
65             
for (int x = x0; x <= x1; x++)
66             {
67                 draw(steep ? y : x, steep ? x : y);
68                 error -= dy;
69                 
if (error < 0)
70                 {
71                     y += ystep;
72                     error += dx;
73                 }
74             }
75         }

76
77         ///
<summary>
78         ///
Draws anti-aliased line and calls <paramref name="draw"/> on every pixel
79         ///
</summary>
80         ///
<remarks>
81         ///
https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
82         ///
</remarks>
83         
public static void RasterAALine(Vector2Int v0, Vector2Int v1, Action<int, int, float> draw)
84         {
85             RasterAALine(v0.x, v0.y, v1.x, v1.y, draw);
86         }

87
88         ///
<summary>
89         ///
Draws anti-aliased line and calls <paramref name="draw"/> on every pixel
90         ///
</summary>
91         ///
<remarks>
92         ///
https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
93         ///
</remarks>
94         
public static void RasterAALine(int x0, int y0, int x1, int y1, Action<int, int, float> draw)
95         {
96             
bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
97             
if (steep)
98             {
99                 PTUtils.Swap(
ref x0, ref y0);
100                 PTUtils.Swap(
ref x1, ref y1);
101             }
102             
if (x0 > x1)
103             {
104                 PTUtils.Swap(
ref x0, ref x1);
105                 PTUtils.Swap(
ref y0, ref y1);
106             }
107
108             
if (steep)
109             {
110                 draw(y0, x0,
1);
111                 draw(y1, x1,
1);
112             }
113             
else
114             {
115                 draw(x0, y0,
1);
116                 draw(x1, y1,
1);
117             }
118             
float dx = x1 - x0;
119             
float dy = y1 - y0;
120             
float gradient = dy/dx;
121             
float y = y0 + gradient;
122             
for (var x = x0 + 1; x <= x1 - 1; x++)
123             {
124                 
if (steep)
125                 {
126                     draw((
int) y, x, 1 - (y - (int) y));
127                     draw((
int) y + 1, x, y - (int) y);
128                 }
129                 
else
130                 {
131                     draw(x, (
int) y, 1 - (y - (int) y));
132                     draw(x, (
int) y + 1, y - (int) y);
133                 }
134                 y += gradient;
135             }
136         }

137
138         ///
<summary>
139         ///
Draws aliased circle and calls <paramref name="draw"/> on every pixel
140         ///
</summary>
141         ///
<remarks>
142         ///
A Rasterizing Algorithm for Drawing Curves
143         ///
http://members.chello.at/easyfilter/bresenham.pdf
144         ///
</remarks>
145         
public static void RasterCircle(Vector2Int v0, int radius, Action<int, int> draw)
146         {
147             RasterCircle(v0.x, v0.y, radius, draw);
148         }

149
150         ///
<summary>
151         ///
Draws aliased circle and calls <paramref name="draw"/> on every pixel
152         ///
</summary>
153         ///
<remarks>
154         ///
A Rasterizing Algorithm for Drawing Curves
155         ///
http://members.chello.at/easyfilter/bresenham.pdf
156         ///
</remarks>
157         
public static void RasterCircle(int x0, int y0, int radius, Action<int, int> draw)
158         {
159             
int x = -radius;
160             
int y = 0;
161             
int error = 2 - 2*radius; // 2 quadrant ◴
162             
while (x < 0)
163             {
164                 draw(x0 - x, y0 + y);
// 1 quadrant ◷
165                 draw(x0 - y, y0 - x);
// 2 quadrant ◴
166                 draw(x0 + x, y0 - y);
// 3 quadrant ◵
167                 draw(x0 + y, y0 + x);
// 4 quadrant ◶
168
169                 
int lastError = error;
170                 
if (y >= error)
171                 {
172                     y++;
173                     error +=
2*y + 1;
174                 }
175
176                 
// Second check is needed to avoid weird pixels at diagonals at some radiuses
177                 
// Example radiuses: 4, 11, 134, 373, 4552
178                 
if (x < lastError || y < error)
179                 {
180                     x++;
181                     error +=
2*x + 1;
182                 }
183             }
184         }

185
186         ///
<summary>
187         ///
Draws filled aliased circle and calls <paramref name="draw"/> on every pixel
188         ///
</summary>
189         
public static void RasterFilledCircle(Vector2Int v0, int radius, Action<int, int> draw)
190         {
191             RasterFilledCircle(v0.x, v0.y, radius, draw);
192         }

193
194         ///
<summary>
195         ///
Draws filled aliased circle and calls <paramref name="draw"/> on every pixel
196         ///
</summary>
197         
public static void RasterFilledCircle(int x0, int y0, int radius, Action<int, int> draw)
198         {
199             
int x = -radius;
200             
int y = 0;
201             
int error = 2 - 2*radius; // 2 quadrant ◴
202             
// lastY must have a different value than y
203             
int lastY = Int32.MaxValue;
204             
while (x < 0)
205             {
206                 
// This check prevents overdraw at poles
207                 
if (lastY != y)
208                 {
209                     DrawHorizontalLine(x0 + x, x0 - x, y0 + y, draw);
// ◠
210                     
// This check prevents overdraw at central horizontal
211                     
if (y != 0)
212                     {
213                         DrawHorizontalLine(x0 + x, x0 - x, y0 - y, draw);
// ◡
214                     }
215                 }
216                 lastY = y;
217
218                 
int lastError = error;
219                 
if (y >= error)
220                 {
221                     y++;
222                     error +=
2*y + 1;
223                 }
224
225                 
// Second check is needed to avoid weird pixels at diagonals at some radiuses
226                 
// Example radiuses: 4, 11, 134, 373, 4552
227                 
if (x < lastError || y < error)
228                 {
229                     x++;
230                     error +=
2*x + 1;
231                 }
232             }
233         }
234
235         
private static void DrawHorizontalLine(int fromX, int toX, int y, Action<int, int> draw)
236         {
237             
for (int x = fromX; x <= toX; x++)
238             {
239                 draw(x, y);
240             }
241         }
242
243         
#endregion Raster
244
245         
public static void WireRay(Action<Vector3, Vector3> drawLine, Ray ray)
246         {
247             drawLine(ray.origin, ray.origin + ray.direction);
248         }
249
250         
public static void WireRay(
251             DebugDrawLine drawLine,
252             Ray ray,
253             Color color,
254             
float duration,
255             
bool depthTest)
256         {
257             drawLine(ray.origin, ray.origin + ray.direction, color, duration, depthTest);
258         }
259
260         
#region WireQuad
261
262         
public static void WireQuadXY(
263             Action<Vector3, Vector3> drawLine,
264             Vector3 position,
265             Quaternion rotation,
266             Vector2 scale)
267         {
268             WireQuad(drawLine, position, rotation, scale, Vector3.right, Vector3.up);
269         }
270
271         
public static void WireQuadXY(
272             DebugDrawLine drawLine,
273             Vector3 position,
274             Quaternion rotation,
275             Vector2 scale,
276             Color color,
277             
float duration,
278             
bool depthTest)
279         {
280             WireQuad(drawLine, position, rotation, scale, Vector3.right, Vector3.up, color, duration, depthTest);
281         }
282
283         
public static void WireQuadXZ(
284             Action<Vector3, Vector3> drawLine,
285             Vector3 position,
286             Quaternion rotation,
287             Vector2 scale)
288         {
289             WireQuad(drawLine, position, rotation, scale, Vector3.right, Vector3.forward);
290         }
291
292         
public static void WireQuadXZ(
293             DebugDrawLine drawLine,
294             Vector3 position,
295             Quaternion rotation,
296             Vector2 scale,
297             Color color,
298             
float duration,
299             
bool depthTest)
300         {
301             WireQuad(drawLine, position, rotation, scale, Vector3.right, Vector3.forward, color, duration, depthTest);
302         }
303
304         
public static void WireQuadYZ(
305             Action<Vector3, Vector3> drawLine,
306             Vector3 position,
307             Quaternion rotation,
308             Vector2 scale)
309         {
310             WireQuad(drawLine, position, rotation, scale, Vector3.up, Vector3.forward);
311         }
312
313         
public static void WireQuadYZ(
314             DebugDrawLine drawLine,
315             Vector3 position,
316             Quaternion rotation,
317             Vector2 scale,
318             Color color,
319             
float duration,
320             
bool depthTest)
321         {
322             WireQuad(drawLine, position, rotation, scale, Vector3.up, Vector3.forward, color, duration, depthTest);
323         }
324
325         
public static void WireQuad(
326             Action<Vector3, Vector3> drawLine,
327             Vector3 position,
328             Quaternion rotation,
329             Vector2 scale,
330             Vector3 planeRight,
331             Vector3 planeForward)
332         {
333             Vector3 right = rotation*planeRight*scale.x;
334             Vector3 forward = rotation*planeForward*scale.y;
335             Vector3 forwardRight = position + right*
0.5f + forward*0.5f;
336             Vector3 backRight = forwardRight - forward;
337             Vector3 backLeft = backRight - right;
338             Vector3 forwardLeft = forwardRight - right;
339
340             drawLine(forwardRight, backRight);
341             drawLine(backRight, backLeft);
342             drawLine(backLeft, forwardLeft);
343             drawLine(forwardLeft, forwardRight);
344         }
345
346         
public static void WireQuad(
347             DebugDrawLine drawLine,
348             Vector3 position,
349             Quaternion rotation,
350             Vector2 scale,
351             Vector3 planeRight,
352             Vector3 planeForward,
353             Color color,
354             
float duration,
355             
bool depthTest)
356         {
357             Vector3 right = rotation*planeRight*scale.x;
358             Vector3 forward = rotation*planeForward*scale.y;
359             Vector3 forwardRight = position + right*
0.5f + forward*0.5f;
360             Vector3 backRight = forwardRight - forward;
361             Vector3 backLeft = backRight - right;
362             Vector3 forwardLeft = forwardRight - right;
363
364             drawLine(forwardRight, backRight, color, duration, depthTest);
365             drawLine(backRight, backLeft, color, duration, depthTest);
366             drawLine(backLeft, forwardLeft, color, duration, depthTest);
367             drawLine(forwardLeft, forwardRight, color, duration, depthTest);
368         }
369
370         
#endregion WireQuad
371
372         
public static void WireCube(
373             Action<Vector3, Vector3> drawLine,
374             Vector3 position,
375             Quaternion rotation,
376             Vector3 scale)
377         {
378             Vector3 right = rotation*Vector3.right*scale.x;
379             Vector3 up = rotation*Vector3.up*scale.y;
380             Vector3 forward = rotation*Vector3.forward*scale.z;
381
382             Vector3 a1 = position + right*
0.5f + up*0.5f + forward*0.5f;
383             Vector3 b1 = a1 - up;
384             Vector3 c1 = b1 - right;
385             Vector3 d1 = a1 - right;
386
387             Vector3 a2 = a1 - forward;
388             Vector3 b2 = b1 - forward;
389             Vector3 c2 = c1 - forward;
390             Vector3 d2 = d1 - forward;
391
392             drawLine(a1, b1);
393             drawLine(b1, c1);
394             drawLine(c1, d1);
395             drawLine(d1, a1);
396
397             drawLine(a2, b2);
398             drawLine(b2, c2);
399             drawLine(c2, d2);
400             drawLine(d2, a2);
401
402             drawLine(a1, a2);
403             drawLine(b1, b2);
404             drawLine(c1, c2);
405             drawLine(d1, d2);
406         }
407
408         
public static void WireCube(
409             DebugDrawLine drawLine,
410             Vector3 position,
411             Quaternion rotation,
412             Vector3 scale,
413             Color color,
414             
float duration,
415             
bool depthTest)
416         {
417             Vector3 right = rotation*Vector3.right*scale.x;
418             Vector3 up = rotation*Vector3.up*scale.y;
419             Vector3 forward = rotation*Vector3.forward*scale.z;
420
421             Vector3 a1 = position + right*
0.5f + up*0.5f + forward*0.5f;
422             Vector3 b1 = a1 - up;
423             Vector3 c1 = b1 - right;
424             Vector3 d1 = a1 - right;
425
426             Vector3 a2 = a1 - forward;
427             Vector3 b2 = b1 - forward;
428             Vector3 c2 = c1 - forward;
429             Vector3 d2 = d1 - forward;
430
431             drawLine(a1, b1, color, duration, depthTest);
432             drawLine(b1, c1, color, duration, depthTest);
433             drawLine(c1, d1, color, duration, depthTest);
434             drawLine(d1, a1, color, duration, depthTest);
435
436             drawLine(a2, b2, color, duration, depthTest);
437             drawLine(b2, c2, color, duration, depthTest);
438             drawLine(c2, d2, color, duration, depthTest);
439             drawLine(d2, a2, color, duration, depthTest);
440
441             drawLine(a1, a2, color, duration, depthTest);
442             drawLine(b1, b2, color, duration, depthTest);
443             drawLine(c1, c2, color, duration, depthTest);
444             drawLine(d1, d2, color, duration, depthTest);
445         }
446
447         
#region WireCircleXY
448
449         
public static void WireCircleXY(
450             Action<Vector3, Vector3> drawLine,
451             Vector3 position,
452             
float radius)
453         {
454             WireCircle(pointOnCircleXY, drawLine, position, radius);
455         }
456
457         
public static void WireCircleXY(
458             DebugDrawLine drawLine,
459             Vector3 position,
460             
float radius,
461             Color color,
462             
float duration,
463             
bool depthTest)
464         {
465             WireCircle(pointOnCircleXY, drawLine, position, radius, color, duration, depthTest);
466         }
467
468         
public static void WireCircleXY(
469             Action<Vector3, Vector3> drawLine,
470             Vector3 position,
471             Quaternion rotation,
472             
float radius)
473         {
474             WireCircle(pointOnCircleXY, drawLine, position, rotation, radius);
475         }
476
477         
public static void WireCircleXY(
478             DebugDrawLine drawLine,
479             Vector3 position,
480             Quaternion rotation,
481             
float radius,
482             Color color,
483             
float duration,
484             
bool depthTest)
485         {
486             WireCircle(pointOnCircleXY, drawLine, position, rotation, radius, color, duration, depthTest);
487         }
488
489         
#endregion WireCircleXY
490
491         
#region WireCircleXZ
492
493         
public static void WireCircleXZ(
494             Action<Vector3, Vector3> drawLine,
495             Vector3 position,
496             
float radius)
497         {
498             WireCircle(pointOnCircleXZ, drawLine, position, radius);
499         }
500
501         
public static void WireCircleXZ(
502             DebugDrawLine drawLine,
503             Vector3 position,
504             
float radius,
505             Color color,
506             
float duration,
507             
bool depthTest)
508         {
509             WireCircle(pointOnCircleXZ, drawLine, position, radius, color, duration, depthTest);
510         }
511
512         
public static void WireCircleXZ(
513             Action<Vector3, Vector3> drawLine,
514             Vector3 position,
515             Quaternion rotation,
516             
float radius)
517         {
518             WireCircle(pointOnCircleXZ, drawLine, position, rotation, radius);
519         }
520
521         
public static void WireCircleXZ(
522             DebugDrawLine drawLine,
523             Vector3 position,
524             Quaternion rotation,
525             
float radius,
526             Color color,
527             
float duration,
528             
bool depthTest)
529         {
530             WireCircle(pointOnCircleXZ, drawLine, position, rotation, radius, color, duration, depthTest);
531         }
532
533         
#endregion WireCircleXZ
534
535         
#region WireCircleYZ
536
537         
public static void WireCircleYZ(
538             Action<Vector3, Vector3> drawLine,
539             Vector3 position,
540             
float radius)
541         {
542             WireCircle(pointOnCircleYZ, drawLine, position, radius);
543         }
544
545         
public static void WireCircleYZ(
546             DebugDrawLine drawLine,
547             Vector3 position,
548             
float radius,
549             Color color,
550             
float duration,
551             
bool depthTest)
552         {
553             WireCircle(pointOnCircleYZ, drawLine, position, radius, color, duration, depthTest);
554         }
555
556         
public static void WireCircleYZ(
557             Action<Vector3, Vector3> drawLine,
558             Vector3 position,
559             Quaternion rotation,
560             
float radius)
561         {
562             WireCircle(pointOnCircleYZ, drawLine, position, rotation, radius);
563         }
564
565         
public static void WireCircleYZ(
566             DebugDrawLine drawLine,
567             Vector3 position,
568             Quaternion rotation,
569             
float radius,
570             Color color,
571             
float duration,
572             
bool depthTest)
573         {
574             WireCircle(pointOnCircleYZ, drawLine, position, rotation, radius, color, duration, depthTest);
575         }
576
577         
#endregion WireCircleYZ
578
579         
#region WireCircle Universal
580
581         
public static void WireCircle(
582             Func<
float, float, Vector3> pointOnCircle,
583             Action<Vector3, Vector3> drawLine,
584             Vector3 position,
585             
float radius)
586         {
587             WireArc(pointOnCircle, drawLine, position, radius,
0, circleSegments, circleSegmentAngle);
588         }
589
590         
public static void WireCircle(
591             Func<
float, float, Vector3> pointOnCircle,
592             DebugDrawLine drawLine,
593             Vector3 position,
594             
float radius,
595             Color color,
596             
float duration,
597             
bool depthTest)
598         {
599             WireArc(pointOnCircle, drawLine, position, radius,
0, circleSegments, circleSegmentAngle, color, duration,
600                 depthTest);
601         }
602
603         
public static void WireCircle(
604             Func<
float, float, Vector3> pointOnCircle,
605             Action<Vector3, Vector3> drawLine,
606             Vector3 position,
607             Quaternion rotation,
608             
float radius)
609         {
610             WireArc(pointOnCircle, drawLine, position, rotation, radius,
0, circleSegments, circleSegmentAngle);
611         }
612
613         
public static void WireCircle(
614             Func<
float, float, Vector3> pointOnCircle,
615             DebugDrawLine drawLine,
616             Vector3 position,
617             Quaternion rotation,
618             
float radius,
619             Color color,
620             
float duration,
621             
bool depthTest)
622         {
623             WireArc(pointOnCircle, drawLine, position, rotation, radius,
0, circleSegments, circleSegmentAngle, color,
624                 duration, depthTest);
625         }
626
627         
#endregion WireCircle Universal
628
629         
#region WireArcXY
630
631         
public static void WireArcXY(
632             Action<Vector3, Vector3> drawLine,
633             Vector3 position,
634             
float radius,
635             
float fromAngle,
636             
float toAngle)
637         {
638             WireArc(pointOnCircleXY, drawLine, position, radius, fromAngle, toAngle);
639         }
640
641         
public static void WireArcXY(
642             DebugDrawLine drawLine,
643             Vector3 position,
644             
float radius,
645             
float fromAngle,
646             
float toAngle,
647             Color color,
648             
float duration,
649             
bool depthTest)
650         {
651             WireArc(pointOnCircleXY, drawLine, position, radius, fromAngle, toAngle, color, duration, depthTest);
652         }
653
654         
public static void WireArcXY(
655             Action<Vector3, Vector3> drawLine,
656             Vector3 position,
657             Quaternion rotation,
658             
float radius,
659             
float fromAngle,
660             
float toAngle)
661         {
662             WireArc(pointOnCircleXY, drawLine, position, rotation, radius, fromAngle, toAngle);
663         }
664
665         
public static void WireArcXY(
666             DebugDrawLine drawLine,
667             Vector3 position,
668             Quaternion rotation,
669             
float radius,
670             
float fromAngle,
671             
float toAngle,
672             Color color,
673             
float duration,
674             
bool depthTest)
675         {
676             WireArc(pointOnCircleXY, drawLine, position, rotation, radius, fromAngle, toAngle, color, duration,
677                 depthTest);
678         }
679
680         
#endregion WireCircleXY
681
682         
#region WireArcXZ
683
684         
public static void WireArcXZ(
685             Action<Vector3, Vector3> drawLine,
686             Vector3 position,
687             
float radius,
688             
float fromAngle,
689             
float toAngle)
690         {
691             WireArc(pointOnCircleXZ, drawLine, position, radius, fromAngle, toAngle);
692         }
693
694         
public static void WireArcXZ(
695             DebugDrawLine drawLine,
696             Vector3 position,
697             
float radius,
698             
float fromAngle,
699             
float toAngle,
700             Color color,
701             
float duration,
702             
bool depthTest)
703         {
704             WireArc(pointOnCircleXZ, drawLine, position, radius, fromAngle, toAngle, color, duration, depthTest);
705         }
706
707         
public static void WireArcXZ(
708             Action<Vector3, Vector3> drawLine,
709             Vector3 position,
710             Quaternion rotation,
711             
float radius,
712             
float fromAngle,
713             
float toAngle)
714         {
715             WireArc(pointOnCircleXZ, drawLine, position, rotation, radius, fromAngle, toAngle);
716         }
717
718         
public static void WireArcXZ(
719             DebugDrawLine drawLine,
720             Vector3 position,
721             Quaternion rotation,
722             
float radius,
723             
float fromAngle,
724             
float toAngle,
725             Color color,
726             
float duration,
727             
bool depthTest)
728         {
729             WireArc(pointOnCircleXZ, drawLine, position, rotation, radius, fromAngle, toAngle, color, duration,
730                 depthTest);
731         }
732
733         
#endregion WireCircleXZ
734
735         
#region WireArcYZ
736
737         
public static void WireArcYZ(
738             Action<Vector3, Vector3> drawLine,
739             Vector3 position,
740             
float radius,
741             
float fromAngle,
742             
float toAngle)
743         {
744             WireArc(pointOnCircleYZ, drawLine, position, radius, fromAngle, toAngle);
745         }
746
747         
public static void WireArcYZ(
748             DebugDrawLine drawLine,
749             Vector3 position,
750             
float radius,
751             
float fromAngle,
752             
float toAngle,
753             Color color,
754             
float duration,
755             
bool depthTest)
756         {
757             WireArc(pointOnCircleYZ, drawLine, position, radius, fromAngle, toAngle, color, duration, depthTest);
758         }
759
760         
public static void WireArcYZ(
761             Action<Vector3, Vector3> drawLine,
762             Vector3 position,
763             Quaternion rotation,
764             
float radius,
765             
float fromAngle,
766             
float toAngle)
767         {
768             WireArc(pointOnCircleYZ, drawLine, position, rotation, radius, fromAngle, toAngle);
769         }
770
771         
public static void WireArcYZ(
772             DebugDrawLine drawLine,
773             Vector3 position,
774             Quaternion rotation,
775             
float radius,
776             
float fromAngle,
777             
float toAngle,
778             Color color,
779             
float duration,
780             
bool depthTest)
781         {
782             WireArc(pointOnCircleYZ, drawLine, position, rotation, radius, fromAngle, toAngle, color, duration,
783                 depthTest);
784         }
785
786         
#endregion WireCircleYZ
787
788         
#region WireArc Universal
789
790         
public static void WireArc(
791             Func<
float, float, Vector3> pointOnCircle,
792             Action<Vector3, Vector3> drawLine,
793             Vector3 position,
794             
float radius,
795             
float fromAngle,
796             
float toAngle)
797         {
798             
int segments;
799             
float segmentAngle;
800             GetSegmentsAndSegmentAngle(fromAngle, toAngle,
out segments, out segmentAngle);
801
802             WireArc(pointOnCircle, drawLine, position, radius, fromAngle, segments, segmentAngle);
803         }
804
805         
public static void WireArc(
806             Func<
float, float, Vector3> pointOnCircle,
807             DebugDrawLine drawLine,
808             Vector3 position,
809             
float radius,
810             
float fromAngle,
811             
float toAngle,
812             Color color,
813             
float duration,
814             
bool depthTest)
815         {
816             
int segments;
817             
float segmentAngle;
818             GetSegmentsAndSegmentAngle(fromAngle, toAngle,
out segments, out segmentAngle);
819
820             WireArc(pointOnCircle, drawLine, position, radius, fromAngle, segments, segmentAngle, color, duration,
821                 depthTest);
822         }
823
824         
public static void WireArc(
825             Func<
float, float, Vector3> pointOnCircle,
826             Action<Vector3, Vector3> drawLine,
827             Vector3 position,
828             Quaternion rotation,
829             
float radius,
830             
float fromAngle,
831             
float toAngle)
832         {
833             
int segments;
834             
float segmentAngle;
835             GetSegmentsAndSegmentAngle(fromAngle, toAngle,
out segments, out segmentAngle);
836
837             WireArc(pointOnCircle, drawLine, position, rotation, radius, fromAngle, segments, segmentAngle);
838         }
839
840         
public static void WireArc(
841             Func<
float, float, Vector3> pointOnCircle,
842             DebugDrawLine drawLine,
843             Vector3 position,
844             Quaternion rotation,
845             
float radius,
846             
float fromAngle,
847             
float toAngle,
848             Color color,
849             
float duration,
850             
bool depthTest)
851         {
852             
int segments;
853             
float segmentAngle;
854             GetSegmentsAndSegmentAngle(fromAngle, toAngle,
out segments, out segmentAngle);
855
856             WireArc(pointOnCircle, drawLine, position, rotation, radius, fromAngle, segments, segmentAngle, color,
857                 duration, depthTest);
858         }
859
860         
public static void WireArc(
861             Func<
float, float, Vector3> pointOnCircle,
862             Action<Vector3, Vector3> drawLine,
863             Vector3 position,
864             
float radius,
865             
float fromAngle,
866             
int segments,
867             
float segmentAngle)
868         {
869             
float currentAngle = fromAngle;
870             
for (var i = 0; i < segments; i++)
871             {
872                 Vector3 a = position + pointOnCircle(radius, currentAngle);
873                 currentAngle += segmentAngle;
874                 Vector3 b = position + pointOnCircle(radius, currentAngle);
875                 drawLine(a, b);
876             }
877         }
878
879         
public static void WireArc(
880             Func<
float, float, Vector3> pointOnCircle,
881             DebugDrawLine drawLine,
882             Vector3 position,
883             
float radius,
884             
float fromAngle,
885             
int segments,
886             
float segmentAngle,
887             Color color,
888             
float duration,
889             
bool depthTest)
890         {
891             
float currentAngle = fromAngle;
892             
for (var i = 0; i < segments; i++)
893             {
894                 Vector3 a = position + pointOnCircle(radius, currentAngle);
895                 currentAngle += segmentAngle;
896                 Vector3 b = position + pointOnCircle(radius, currentAngle);
897                 drawLine(a, b, color, duration, depthTest);
898             }
899         }
900
901         
public static void WireArc(
902             Func<
float, float, Vector3> pointOnCircle,
903             Action<Vector3, Vector3> drawLine,
904             Vector3 position,
905             Quaternion rotation,
906             
float radius,
907             
float fromAngle,
908             
int segments,
909             
float segmentAngle)
910         {
911             
float currentAngle = fromAngle;
912             
for (var i = 0; i < segments; i++)
913             {
914                 Vector3 a = position + rotation*pointOnCircle(radius, currentAngle);
915                 currentAngle += segmentAngle;
916                 Vector3 b = position + rotation*pointOnCircle(radius, currentAngle);
917                 drawLine(a, b);
918             }
919         }
920
921         
public static void WireArc(
922             Func<
float, float, Vector3> pointOnCircle,
923             DebugDrawLine drawLine,
924             Vector3 position,
925             Quaternion rotation,
926             
float radius,
927             
float fromAngle,
928             
int segments,
929             
float segmentAngle,
930             Color color,
931             
float duration,
932             
bool depthTest)
933         {
934             
float currentAngle = fromAngle;
935             
for (var i = 0; i < segments; i++)
936             {
937                 Vector3 a = position + rotation*pointOnCircle(radius, currentAngle);
938                 currentAngle += segmentAngle;
939                 Vector3 b = position + rotation*pointOnCircle(radius, currentAngle);
940                 drawLine(a, b, color, duration, depthTest);
941             }
942         }
943
944         
#endregion WireArc Universal
945
946         
public static void WireSphere(
947             Action<Vector3, Vector3> drawLine,
948             Vector3 position,
949             Quaternion rotation,
950             
float radius)
951         {
952             WireCircleXY(drawLine, position, rotation, radius);
953             WireCircleXZ(drawLine, position, rotation, radius);
954             WireCircleYZ(drawLine, position, rotation, radius);
955         }
956
957         
public static void WireSphere(
958             DebugDrawLine drawLine,
959             Vector3 position,
960             Quaternion rotation,
961             
float radius,
962             Color color,
963             
float duration,
964             
bool depthTest)
965         {
966             WireCircleXY(drawLine, position, rotation, radius, color, duration, depthTest);
967             WireCircleXZ(drawLine, position, rotation, radius, color, duration, depthTest);
968             WireCircleYZ(drawLine, position, rotation, radius, color, duration, depthTest);
969         }
970
971         
public static void WireHemisphere(
972             Action<Vector3, Vector3> drawLine,
973             Vector3 position,
974             Quaternion rotation,
975             
float radius)
976         {
977             WireArcXY(drawLine, position, rotation, radius, -
90, 90);
978             WireCircleXZ(drawLine, position, rotation, radius);
979             WireArcYZ(drawLine, position, rotation, radius,
0, 180);
980         }
981
982         
public static void WireHemisphere(
983             DebugDrawLine drawLine,
984             Vector3 position,
985             Quaternion rotation,
986             
float radius,
987             Color color,
988             
float duration,
989             
bool depthTest)
990         {
991             WireArcXY(drawLine, position, rotation, radius, -
90, 90, color, duration, depthTest);
992             WireCircleXZ(drawLine, position, rotation, radius, color, duration, depthTest);
993             WireArcYZ(drawLine, position, rotation, radius,
0, 180, color, duration, depthTest);
994         }
995
996         
public static void WireCone(
997             Action<Vector3, Vector3> drawLine,
998             Vector3 position,
999             Quaternion rotation,
1000             
float apexRadius,
1001             
float angle,
1002             
float length)
1003         {
1004             Vector3 upperCenter = position + rotation*Vector3.up*length;
1005             
float upperRadius = Mathf.Tan(angle*Mathf.Deg2Rad)*length + apexRadius;
1006             WireCircleXZ(drawLine, upperCenter, rotation, upperRadius);
1007
1008             Vector3 a2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
0);
1009             Vector3 b2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
90);
1010             Vector3 c2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
180);
1011             Vector3 d2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
270);
1012
1013             
if (apexRadius == 0)
1014             {
1015                 drawLine(position, a2);
1016                 drawLine(position, b2);
1017                 drawLine(position, c2);
1018                 drawLine(position, d2);
1019             }
1020             
else
1021             {
1022                 WireCircleXZ(drawLine, position, rotation, apexRadius);
1023
1024                 Vector3 a1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
0);
1025                 Vector3 b1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
90);
1026                 Vector3 c1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
180);
1027                 Vector3 d1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
270);
1028
1029                 drawLine(a1, a2);
1030                 drawLine(b1, b2);
1031                 drawLine(c1, c2);
1032                 drawLine(d1, d2);
1033             }
1034         }
1035
1036         
public static void WireCone(
1037             DebugDrawLine drawLine,
1038             Vector3 position,
1039             Quaternion rotation,
1040             
float apexRadius,
1041             
float angle,
1042             
float length,
1043             Color color,
1044             
float duration,
1045             
bool depthTest)
1046         {
1047             Vector3 upperCenter = position + rotation*Vector3.up*length;
1048             
float upperRadius = Mathf.Tan(angle*Mathf.Deg2Rad)*length + apexRadius;
1049             WireCircleXZ(drawLine, upperCenter, rotation, upperRadius, color, duration, depthTest);
1050
1051             Vector3 a2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
0);
1052             Vector3 b2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
90);
1053             Vector3 c2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
180);
1054             Vector3 d2 = upperCenter + rotation*PTUtils.PointOnCircle3XZ(upperRadius,
270);
1055
1056             
if (apexRadius == 0)
1057             {
1058                 drawLine(position, a2, color, duration, depthTest);
1059                 drawLine(position, b2, color, duration, depthTest);
1060                 drawLine(position, c2, color, duration, depthTest);
1061                 drawLine(position, d2, color, duration, depthTest);
1062             }
1063             
else
1064             {
1065                 WireCircleXZ(drawLine, position, rotation, apexRadius, color, duration, depthTest);
1066
1067                 Vector3 a1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
0);
1068                 Vector3 b1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
90);
1069                 Vector3 c1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
180);
1070                 Vector3 d1 = rotation*PTUtils.PointOnCircle3XZ(apexRadius,
270);
1071
1072                 drawLine(a1, a2, color, duration, depthTest);
1073                 drawLine(b1, b2, color, duration, depthTest);
1074                 drawLine(c1, c2, color, duration, depthTest);
1075                 drawLine(d1, d2, color, duration, depthTest);
1076             }
1077         }
1078
1079         
private static void GetSegmentsAndSegmentAngle(
1080             
float fromAngle,
1081             
float toAngle,
1082             
out int segments,
1083             
out float segmentAngle)
1084         {
1085             
float range = toAngle - fromAngle;
1086             
if (range > circleSegmentAngle)
1087             {
1088                 segments = Mathf.FloorToInt(range/circleSegmentAngle);
1089                 segmentAngle = range/segments;
1090             }
1091             
else
1092             {
1093                 segments =
1;
1094                 segmentAngle = range;
1095             }
1096         }
1097     }
1098 }


Gõ tìm kiếm nhanh...